package com.samsung.handler;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlSerializer;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.util.Log;
import android.util.Xml;

import com.samsung.sbackup.FragmentSettingsPreference;

public class CalendarHandler {
	Cursor calendars, events, reminders;
	String file = "";
	public volatile int progress;
	public int totalRecord;
	String path;
	NodeList nList, nList_1, nList_2;
	boolean isError;
	String errorMessage;

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public boolean isError() {
		return isError;
	}

	public void setError(boolean isError) {
		this.isError = isError;
	}

	Context context;
	ContentResolver cr;
	SharedPreferences sharedPref;

	public String getFile() {
		return file;
	}

	public void setFile(String file) {
		this.file = file;
	}

	public CalendarHandler(Context ctx) {

		setError(false);
		setErrorMessage("No errors");
		this.context = ctx;
		cr = context.getContentResolver();
		sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
		String folder = sharedPref.getString(
				FragmentSettingsPreference.BACKUP_PATH, "/");

		String[] PROJECTION = new String[] { Calendars._ID,
				Calendars.ACCOUNT_NAME, Calendars.ACCOUNT_TYPE, Calendars.NAME,
				Calendars.CALENDAR_DISPLAY_NAME, Calendars.OWNER_ACCOUNT,
				Calendars.CALENDAR_COLOR, Calendars.CALENDAR_ACCESS_LEVEL,
				Calendars.CALENDAR_TIME_ZONE, Calendars.SYNC_EVENTS };
		calendars = cr.query(Calendars.CONTENT_URI, PROJECTION, null, null,
				null);
		String[] PROJECTION_1 = new String[] { Events._ID, Events.CALENDAR_ID,
				Events.TITLE, Events.DESCRIPTION, Events.EVENT_LOCATION,
				Events.EVENT_TIMEZONE, Events.ALL_DAY, Events.DTSTART,
				Events.DTEND, Events.DURATION, Events.DELETED, Events.EXDATE,
				Events.EXRULE, Events.RDATE, Events.RRULE, Events.HAS_ALARM,
				Events.STATUS, Events.SELF_ATTENDEE_STATUS, Events.ORGANIZER,
				Events.HAS_ATTENDEE_DATA, Events.ACCESS_LEVEL,
				Events.AVAILABILITY };
		String selection = "(" + Events.DELETED + "=?)";
		String[] selectionArgs = new String[] { "0" };

		events = cr.query(Events.CONTENT_URI, PROJECTION_1, selection,
				selectionArgs, null);
		SimpleDateFormat sf = new SimpleDateFormat("HHmmddMMyyyy",
				Locale.getDefault());
		String date = sf.format(Calendar.getInstance().getTime());
		setFile(folder + "/calendar_" + date + ".xml");
		// totalRecord = events.getCount() + calendars.getCount();
		totalRecord = events.getCount();
	}

	public CalendarHandler(String path, Context ctx) {
		this.context = ctx;
		cr = context.getContentResolver();
		this.path = path;

		File fXmlFile = new File(path.replaceFirst("zip", "xml"));
		Log.e("path", path.replaceFirst("zip", "xml"));
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder;
		try {
			dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
			doc.getDocumentElement().normalize();

			nList = doc.getElementsByTagName("Calendar");
			nList_1 = doc.getElementsByTagName("Events");
			nList_2 = doc.getElementsByTagName("Reminders");
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			setError(true);
			setErrorMessage("Error: " + e.toString());
		} catch (SAXException e) {
			e.printStackTrace();
			setError(true);
			setErrorMessage("Error: " + e.toString());
		} catch (IOException e) {
			e.printStackTrace();
			setError(true);
			setErrorMessage("Error: " + e.toString());
		}
		totalRecord = nList_1.getLength();
	}

	public void backup() {
		try {
			FileOutputStream fos = new FileOutputStream(new File(getFile()));
			XmlSerializer serializer = Xml.newSerializer();
			serializer = Xml.newSerializer();
			serializer.setFeature(
					"http://xmlpull.org/v1/doc/features.html#indent-output",
					true);
			serializer.setOutput(fos, "UTF-8");
			serializer.startDocument("UTF-8", true);
			serializer.startTag("", "allCalendar");
			// writeCalendar(fos, serializer);
			writeEvents(fos, serializer);
			serializer.endTag("", "allCalendar");
			serializer.endDocument();
			serializer.flush();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
			setError(true);
			setErrorMessage("Error: " + e.toString());
		}

	}

	public void restoreCalendar(ContentResolver cr) {
		boolean checkDuplicate;
		Uri uri, ur = null;
		try {

			ContentValues values = new ContentValues();
			String selection = "(" + Events.DELETED + "=?)";
			String[] selectionArgs = new String[] { "0" };
			Cursor c = cr.query(Events.CONTENT_URI, null, selection,
					selectionArgs, null);
			ArrayList<String> arrayDateStart = new ArrayList<String>();
			ArrayList<String> arrayDateEnd = new ArrayList<String>();
			ArrayList<String> arrayTitle = new ArrayList<String>();
			if (c.moveToFirst())
				do {
					arrayDateStart.add(c.getString(c
							.getColumnIndexOrThrow(Events.DTSTART)));
					arrayDateEnd
							.add(""
									+ c.getString(c
											.getColumnIndexOrThrow(Events.DTEND)));
					arrayTitle
							.add(""
									+ c.getString(c
											.getColumnIndexOrThrow(Events.TITLE)));
				} while (c.moveToNext());

			for (int temp = 0; temp < nList_1.getLength(); temp++) {
				checkDuplicate = true;
				progress += 1;
				values.clear();
				Node nNode = nList_1.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {
					Element eElement = (Element) nNode;
					values.put(Events.CALENDAR_ID,
							"" + eElement.getAttribute("calendar_id"));
					values.put("title", "" + eElement.getAttribute("title"));
					if (!eElement.getAttribute("description").equals("null"))
						values.put("description",
								eElement.getAttribute("description"));
					if (!eElement.getAttribute("eventLocation").equals("null"))
						values.put("eventLocation",
								eElement.getAttribute("eventLocation"));
					values.put("eventTimezone",
							"" + eElement.getAttribute("eventTimezone"));
					values.put("allDay", "" + eElement.getAttribute("allDay"));
					values.put("dtstart", "" + eElement.getAttribute("dtstart"));
					if (!(eElement.getAttribute("dtend").equals("null"))
							&& !(eElement.getAttribute("dtend").equals("")))
						values.put("dtend", "" + eElement.getAttribute("dtend"));
					if (!(eElement.getAttribute("duration").equals("null"))
							&& (eElement.getAttribute("dtend").equals("null")))
						values.put("duration",
								"" + eElement.getAttribute("duration"));
					values.put("deleted", "" + eElement.getAttribute("deleted"));

					if (!eElement.getAttribute("exdate").equals("null"))
						values.put("exdate",
								"" + eElement.getAttribute("exdate"));
					if (!eElement.getAttribute("exrule").equals("null"))
						values.put("exrule",
								"" + eElement.getAttribute("exrule"));
					if (!eElement.getAttribute("rdate").equals("null"))
						values.put("rdate", "" + eElement.getAttribute("rdate"));
					if (!eElement.getAttribute("rrule").equals("null"))
						values.put("rrule", "" + eElement.getAttribute("rrule"));

					values.put("hasAlarm",
							"" + eElement.getAttribute("hasAlarm"));
					values.put("eventStatus",
							"" + eElement.getAttribute("eventStatus"));
					values.put("selfAttendeeStatus",
							"" + eElement.getAttribute("selfAttendeeStatus"));
					values.put("organizer",
							"" + eElement.getAttribute("organizer"));
					values.put("hasAttendeeData",
							"" + eElement.getAttribute("hasAttendeeData"));
					values.put("accessLevel",
							"" + eElement.getAttribute("accessLevel"));
					values.put("availability",
							"" + eElement.getAttribute("availability"));

					for (int i = 0; i < arrayDateStart.size(); i++) {
						Log.e("size", "" + arrayDateEnd.size());
						// Log.e("dtend", arrayDateEnd.get(i).toString());
						if (eElement.getAttribute("dtstart").equals(
								arrayDateStart.get(i))
								&& (eElement.getAttribute("dtend")
										.equals(arrayDateEnd.get(i)))
								&& (eElement.getAttribute("title")
										.equals(arrayTitle.get(i)))) {
							checkDuplicate = false;
							break;
						}
					}
					if (checkDuplicate == true) {

						uri = cr.insert(Events.CONTENT_URI, values);
						Log.e("vao ", "dc  " + uri);
						Log.e("uri", "" + uri.getLastPathSegment());
						if (eElement.getAttribute("hasAlarm").equals("1")) {
							Log.e("aef", "awevav    " + nList_2.getLength());
							for (int i = 0; i < nList_2.getLength(); i++) {
								Node nNode_2 = nList_2.item(i);
								if (nNode_2.getNodeType() == Node.ELEMENT_NODE) {

									Element eElement_2 = (Element) nNode_2;
									if (eElement_2.getAttribute("event_id")
											.equals(eElement
													.getAttribute("_id"))) {

										ContentValues vl = new ContentValues();
										vl.put("event_id",
												"" + uri.getLastPathSegment());
										vl.put("method",
												""
														+ eElement_2
																.getAttribute("method"));
										vl.put("minutes",
												""
														+ eElement_2
																.getAttribute("minutes"));
										ur = cr.insert(Reminders.CONTENT_URI,
												vl);
									}
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			setError(true);
			setErrorMessage("Error: " + e.toString());
		}
	}

	public void writeCalendar(FileOutputStream fos, XmlSerializer serializer) {

		if (calendars.moveToFirst())
			do {
				try {
					progress++;
					serializer.startTag("", "Calendar");
					serializer.attribute("", "_id",
							String.valueOf(calendars.getString(0)));
					serializer.attribute("", "account_name",
							String.valueOf(calendars.getString(1)));
					serializer.attribute("", "account_type",
							String.valueOf(calendars.getString(2)));
					serializer.attribute("", "name",
							String.valueOf(calendars.getString(3)));
					serializer.attribute("", "calendar_displayName",
							String.valueOf(calendars.getString(4)));
					serializer.attribute("", "ownerAccount",
							String.valueOf(calendars.getString(5)));
					serializer.attribute("", "calendar_color",
							String.valueOf(calendars.getString(6)));
					serializer.attribute("", "calendar_access_level",
							String.valueOf(calendars.getString(7)));
					serializer.attribute("", "calendar_timezone",
							String.valueOf(calendars.getString(8)));
					serializer.attribute("", "sync_events",
							String.valueOf(calendars.getString(9)));
					serializer.endTag("", "Calendar");
				} catch (IOException e) {
					e.printStackTrace();
					setError(true);
					setErrorMessage("Error: " + e.toString());
				}
			} while (calendars.moveToNext());
	}

	public void writeEvents(FileOutputStream fos, XmlSerializer serializer) {

		if (events.moveToFirst())
			do {
				try {
					progress++;
					serializer.startTag("", "Events");
					serializer.attribute("", "_id",
							String.valueOf(events.getString(0)));
					serializer.attribute("", "calendar_id",
							String.valueOf(events.getString(1)));
					serializer.attribute("", "title",
							String.valueOf(events.getString(2)));
					serializer.attribute("", "description",
							String.valueOf(events.getString(3)));
					serializer.attribute("", "eventLocation",
							String.valueOf(events.getString(4)));
					serializer.attribute("", "eventTimezone",
							String.valueOf(events.getString(5)));
					serializer.attribute("", "allDay",
							String.valueOf(events.getString(6)));
					serializer.attribute("", "dtstart",
							String.valueOf(events.getString(7)));
					serializer.attribute("", "dtend",
							String.valueOf(events.getString(8)));
					serializer.attribute("", "duration",
							String.valueOf(events.getString(9)));
					serializer.attribute("", "deleted",
							String.valueOf(events.getString(10)));
					serializer.attribute("", "exdate",
							String.valueOf(events.getString(11)));
					serializer.attribute("", "exrule",
							String.valueOf(events.getString(12)));
					serializer.attribute("", "rdate",
							String.valueOf(events.getString(13)));
					serializer.attribute("", "rrule",
							String.valueOf(events.getString(14)));
					serializer.attribute("", "hasAlarm",
							String.valueOf(events.getString(15)));
					serializer.attribute("", "eventStatus",
							String.valueOf(events.getString(16)));
					serializer.attribute("", "selfAttendeeStatus",
							String.valueOf(events.getString(17)));
					serializer.attribute("", "organizer",
							String.valueOf(events.getString(18)));
					serializer.attribute("", "hasAttendeeData",
							String.valueOf(events.getString(19)));
					serializer.attribute("", "accessLevel",
							String.valueOf(events.getString(20)));
					serializer.attribute("", "availability",
							String.valueOf(events.getString(21)));

					serializer.endTag("", "Events");
					if (events.getString(15).equals("1")) {
						String selection = "(" + "event_id=" + "?)";
						String[] selectionArgs = new String[] { events
								.getString(0) };

						Cursor r = context.getContentResolver().query(
								Reminders.CONTENT_URI, null, selection,
								selectionArgs, null);
						if (r.moveToFirst())
							do {
								serializer.startTag("", "Reminders");
								serializer.attribute("", "event_id",
										events.getString(0));
								serializer
										.attribute(
												"",
												"method",
												String.valueOf(r.getString(r
														.getColumnIndexOrThrow(Reminders.METHOD))));
								serializer
										.attribute(
												"",
												"minutes",
												String.valueOf(r.getString(r
														.getColumnIndexOrThrow(Reminders.MINUTES))));
								serializer.endTag("", "Reminders");
							} while (r.moveToNext());

					}

				} catch (IOException e) {
					e.printStackTrace();
					setError(true);
					setErrorMessage("Error: " + e.toString());
				}
			} while (events.moveToNext());
	}
}
